<template>
  <div class="list-container">
    <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
      <van-list
        v-model:loading="loading"
        :finished="finished"
        finished-text="没有更多了"
        @load="onLoad"
        :immediate-check="false"
      >
        <van-cell v-for="item in list" :key="item.id" class="list-item" @click="handleItemClick(item)">
          <div class="item-content">
            <van-image class="item-image" :src="item.image" width="80" height="80" fit="cover" />
            <div class="item-info">
              <div class="item-title">{{ item.title }}</div>
              <div class="item-desc">{{ item.description }}</div>
              <div class="item-bottom">
                <span class="item-price">¥{{ item.price }}</span>
                <van-tag type="primary">{{ item.tag }}</van-tag>
              </div>
            </div>
          </div>
        </van-cell>
      </van-list>
    </van-pull-refresh>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from "vue";
import { List, PullRefresh, Cell, Image, Tag, Toast } from "vant";
import type { ListItemData } from "./types";

// 组件注册
const VanList = List;
const VanPullRefresh = PullRefresh;
const VanCell = Cell;
const VanImage = Image;
const VanTag = Tag;

// 响应式数据
const list = ref<ListItemData[]>([]);
const loading = ref(false);
const finished = ref(false);
const refreshing = ref(false);
const page = ref(1);
const pageSize = 10;

// 生成模拟数据
const generateMockData = (count: number): ListItemData[] => {
  return Array.from({ length: count }, (_, i) => ({
    id: `item-${page.value}-${i}`,
    title: `商品 ${page.value}-${i + 1}`,
    description: `这是商品 ${page.value}-${i + 1} 的描述信息`,
    image: `https://picsum.photos/200/200?random=${page.value}${i}`,
    price: (Math.random() * 1000).toFixed(2),
    tag: ["新品", "热卖", "推荐"][Math.floor(Math.random() * 3)],
  }));
};

// 加载数据
const loadData = async (isRefresh = false) => {
  try {
    // 模拟API请求延迟
    await new Promise((resolve) => setTimeout(resolve, 800));

    const newData = generateMockData(pageSize);

    if (isRefresh) {
      list.value = newData;
    } else {
      list.value = [...list.value, ...newData];
    }

    // 判断是否加载完毕
    if (newData.length < pageSize) {
      finished.value = true;
    } else {
      page.value++;
    }
  } catch (error) {
    Toast.fail("加载失败");
  } finally {
    loading.value = false;
    refreshing.value = false;
  }
};

// 上拉加载更多
const onLoad = () => {
  if (refreshing.value) {
    refreshing.value = false;
  }
  loadData();
};

// 下拉刷新
const onRefresh = () => {
  // 清空列表数据
  finished.value = false;
  loading.value = true;
  page.value = 1;
  loadData(true);
};

// 点击项目
const handleItemClick = (item: ListItemData) => {
  Toast(`点击了 ${item.title}`);
};

// 初始化加载数据
onMounted(() => {
  loading.value = true;
  loadData();
});
</script>

<style scoped>
.list-container {
  max-height: 83vh;
  overflow: hidden;
  padding: 10px 15px;
  overflow-y: auto; /* 垂直滚动 */
}

.list-item {
  padding: 12px;
}

.item-content {
  display: flex;
}

.item-image {
  flex-shrink: 0;
  margin-right: 12px;
  border-radius: 4px;
}

.item-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow: hidden;
}

.item-title {
  font-size: 16px;
  font-weight: bold;
  margin-bottom: 6px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.item-desc {
  font-size: 12px;
  color: #666;
  margin-bottom: 8px;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.item-bottom {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.item-price {
  color: #ff4444;
  font-size: 16px;
  font-weight: bold;
}

/* 响应式调整 */
@media (max-width: 480px) {
  .list-item {
    padding: 8px;
  }

  .item-image {
    width: 70px;
    height: 70px;
    margin-right: 8px;
  }

  .item-title {
    font-size: 14px;
  }

  .item-desc {
    font-size: 11px;
  }

  .item-price {
    font-size: 14px;
  }
}
</style>
